/*
 * Copyright (c) 2018 LingoChamp Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.liulishuo.okdownload.sample.util.task_list

import android.content.Context
import android.util.Log
import android.widget.SeekBar
import android.widget.Toast
import com.liulishuo.okdownload.DownloadContext
import com.liulishuo.okdownload.DownloadContextListener
import com.liulishuo.okdownload.DownloadTask
import com.liulishuo.okdownload.OkDownload
import com.liulishuo.okdownload.sample.util.DemoUtil
import com.liulishuo.okdownload.sample.util.queue.TagUtil
import java.io.File

private const val childDir = "task_list"

const val download_url =
    "https://dlied4.szyd.tcdnos.com/myapp/1104466820/cos.release-40109/10040714_com.tencent.tmgp.sgame_a3629310_10.3.1.1_LY5dBW.apk?mkey=lego_ztc&f=00&sche_type=7&cip=180.111.222.147&proto=https&access_type=&sign=1748232096.0e7136e2de9fa946f06c43b865d9507f.86d3a3914da4675ef61279795b3fc956.ij312w6dDnBXsHWazIkLylKTiQ5Xl5iWN-D1_audNVs&tx_domain=dlied4.myapp.com&tx_path=%2Fmyapp%2F1104466820%2F&tx_id=6c9382a8c8"

@Suppress("SAFE_CALL_WILL_CHANGE_NULLABILITY")
class TaskConstroller {

    private val taskList = arrayListOf<DownloadTask>()
    private var downloadContext: DownloadContext? = null
    private var queueDir: File? = null
    private val listener = TaskQueueListener()
    private lateinit var context: Context

    fun start(context: Context, listener: DownloadContextListener) {
        this.context = context
        val parentFile = DemoUtil.getParentFile(context)
        /*
            val build = DownloadContext.QueueSet().apply {
                setParentPathFile(File(parentFile, childDir))
                minIntervalMillisCallbackProcess = 300
            }.commit()

            repeat(10) {
                val task = build.bind(download_url)
                TagUtil.saveTaskName(task, "王者荣耀-$it")
            }
            build.setListener(listener)
            downloadContext = build.build().also { taskList.addAll(it.tasks) }
        */


        repeat(10) {
            val task = DownloadTask.Builder(download_url, File(parentFile, childDir))
                .setFilename("wzry_$it.apk")
                .setMinIntervalMillisCallbackProcess(300) // 设置回调间隔(毫秒)
                .setPassIfAlreadyCompleted(false)
                .build()
            // task.enqueue(this.listener)
            taskList.add(task)
        }

    }

    fun setPriority(task: DownloadTask, priority: Int) {
        val newTask = task.toBuilder().setPriority(priority).build()
        downloadContext = downloadContext?.toBuilder()
            ?.bindSetTask(newTask)
            ?.build()
            ?.also {
                taskList.clear()
                taskList.addAll(it.tasks)
            }
        newTask.setTags(task)
        TagUtil.savePriority(newTask, priority)
    }

    fun deleteFiles() {
        if (queueDir != null) {
            val children = queueDir!!.list()
            if (children != null) {
                for (child in children) {
                    if (!File(queueDir, child).delete()) {
                        Log.w("QueueController", "delete $child failed!")
                    }
                }
            }

            if (!queueDir!!.delete()) {
                Log.w("QueueController", "delete $queueDir failed!")
            }
        }

        for (task in taskList) {
            TagUtil.clearProceedTask(task)
        }
    }

    fun start(isSerial: Boolean) {
        this.downloadContext?.start(listener, isSerial)
    }

    fun stop() {
        if (this.downloadContext?.isStarted == true) {
            this.downloadContext?.stop()
        }
    }

    fun cancle(task: DownloadTask) {
        OkDownload.with().downloadDispatcher().cancel(task)
        task.addTag(KEY_START, false)
    }

    fun start(task: DownloadTask) {
        if (task.listener == null) {
            task.replaceListener(listener)
        }
        OkDownload.with().downloadDispatcher().enqueue(task)
        task.addTag(KEY_START, true)
    }

    internal fun bind(holder: ListTaskAdapter.TaskViewHolder, position: Int) {
        val task = taskList[position]
        Log.d(TAG, "bind " + position + " for " + task.url)

        listener.bind(task, holder)
        listener.resetInfo(task, holder)

        // priority
        val priority = TagUtil.getPriority(task)
        holder.priorityTv.text = holder.priorityTv.context.getString(
            com.liulishuo.okdownload.sample.R.string.priority,
            priority
        )
        // 设置优先级 priority
        holder.prioritySb.progress = priority
        if (this.downloadContext?.isStarted == true) {
            holder.prioritySb.isEnabled = false
        } else {
            holder.prioritySb.isEnabled = true
            holder.prioritySb.setOnSeekBarChangeListener(
                object : SeekBar.OnSeekBarChangeListener {
                    var isFromUser: Boolean = false

                    override fun onProgressChanged(
                        seekBar: SeekBar,
                        progress: Int,
                        fromUser: Boolean
                    ) {
                        isFromUser = fromUser
                    }

                    override fun onStartTrackingTouch(seekBar: SeekBar) {}

                    override fun onStopTrackingTouch(seekBar: SeekBar) {
                        if (isFromUser) {
                            val taskPriority = seekBar.progress
                            setPriority(task, taskPriority)
                            holder.priorityTv.text =
                                seekBar.context.getString(
                                    com.liulishuo.okdownload.sample.R.string.priority,
                                    taskPriority
                                )
                        }
                    }
                })
        }

        holder.stateBtn.setOnClickListener {
            val tastakName = TagUtil.getTaskName(task)
            val isStart = task.getTag(KEY_START) as? Boolean
            if (isStart == null || isStart == false) {
                start(task)
            } else {
                cancle(task)
            }
            showToast("tastakName = $tastakName")
        }
    }

    fun size(): Int = taskList.size

    fun showToast(msg: String) {
        Toast.makeText(context, msg, Toast.LENGTH_LONG).show()
    }

    companion object {
        private const val TAG = "QueueController"
        private const val KEY_START = 103
    }
}